package com.hyperzsoft.budget;

import java.util.Calendar;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.hyperzsoft.utils.DateUtils;

public class CalendarDialog extends Activity implements OnClickListener {
	private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    
    private GestureDetector gestureDetector;
    private OnTouchListener gestureListener;
    
    private int REL_SWIPE_MIN_DISTANCE;
    private int REL_SWIPE_MAX_OFF_PATH;
    private int REL_SWIPE_THRESHOLD_VELOCITY;
    
    private int mMonthToDisplay;
    private Calendar mCal;
    
    private Dialog mDialog;
    
    public int mPrevId = -1;
    
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//setContentView(R.layout.calendar);
		
		REL_SWIPE_MIN_DISTANCE = (int)(SWIPE_MIN_DISTANCE * getResources().getDisplayMetrics().densityDpi / 160.0f);
	    REL_SWIPE_MAX_OFF_PATH = (int)(SWIPE_MAX_OFF_PATH * getResources().getDisplayMetrics().densityDpi / 160.0f);
	    REL_SWIPE_THRESHOLD_VELOCITY = (int)(SWIPE_THRESHOLD_VELOCITY * getResources().getDisplayMetrics().densityDpi / 160.0f);
		
		// Gesture detection
        gestureDetector = new GestureDetector(new customGestureDetector());
        gestureListener = new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    Toast.makeText(getApplicationContext(), v.getId(), Toast.LENGTH_SHORT).show();
                	return true;
                }
                return false;
            }
        };
        
		//default the calendar to display current month
        mCal = Calendar.getInstance();
        mMonthToDisplay = mCal.get(Calendar.MONTH);
		
		mDialog = new Dialog(this, R.style.EditTypesDialog);
		mDialog.setContentView(R.layout.calendar);	
		mDialog.setCancelable(true);
		mDialog.setOwnerActivity(this);
		
        SetGridViewAdapter();
        
        GridView gv = (GridView) mDialog.findViewById(R.id.calendar_grid);
        
		gv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
				View prevSelected;
				
				if (mPrevId != -1) {
					prevSelected = parent.findViewById(mPrevId);
					prevSelected.postInvalidate();
					prevSelected.setBackgroundResource(((Boolean)prevSelected.getTag(R.string.alt) == true) ? R.drawable.calendar_item_alt_unselected : R.drawable.calendar_item_unselected);
				}
				
				view.postInvalidate();
				view.setBackgroundResource(((Boolean)((TextView) view).getTag(R.string.alt) == true) ? R.drawable.calendar_item_alt_selected : R.drawable.calendar_item_selected);
				
				// When clicked, show a toast with the TextView text 
				String toastStr = "";
				toastStr += DateUtils.getWeekdayName( ((Number)((TextView) view).getTag(R.string.day_of_week)).intValue()) + " ";
				toastStr += DateUtils.getMonthName(((Number)((TextView) view).getTag(R.string.month_val)).intValue(), true) + " ";
				toastStr += ((TextView)view).getText().toString() + " ";
				toastStr += (((TextView) view).getTag(R.string.year_val));
				//Toast.makeText(getBaseContext(), toastStr, Toast.LENGTH_SHORT).show();
				mPrevId = ((TextView) view).getId();
			}
		});
		
		gv.setOnTouchListener(gestureListener);
		
		//SetupMonthsInYearGrid();
		
		mDialog.show();
	}
//	
//	public void SetupMonthsInYearGrid() {
//		TableLayout tl = (TableLayout) mDialog.findViewById(R.id.month_selection);
//		TableRow tr;
//		ImageView iv;
//		int month = 1;
//		
//		for (int y=1;y<=4;y++) {
//			tr = new TableRow(getApplicationContext());
//			
//			for (int x=1;x<=3;x++) {
//				iv = new ImageView(getApplicationContext());
//				iv.setScaleType(ScaleType.FIT_CENTER);
//				iv.setAdjustViewBounds(true);
//				iv.setImageResource(getResources().getIdentifier("com.hyperzsoft.budget:drawable/" + DateUtils.getMonthName(month, true), null, null));
//				tr.addView(iv);
//				month++;
//			}
//			
//			tl.addView(tr);
//		}
//	}
//	
	public void SetGridViewAdapter() {
		TextView monthText = (TextView) mDialog.findViewById(R.id.calendar_header);
		monthText.setText(DateUtils.getMonthName(mMonthToDisplay) +
				" - " + mCal.get(Calendar.YEAR));
		
		((GridView) mDialog.findViewById(R.id.calendar_grid)).setAdapter(new 
				calendarGridAdapter(getApplicationContext(), mMonthToDisplay));
		
	}
	
	public void rollMonth(boolean increment) {
		mCal.roll(Calendar.MONTH, increment);
		mMonthToDisplay = mCal.get(Calendar.MONTH);
	}
	
	@Override
	public void onClick(DialogInterface arg0, int arg1) {
		// TODO Auto-generated method stub
	}
	
	private class customGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            try {
                if (Math.abs(e1.getY() - e2.getY()) > REL_SWIPE_MAX_OFF_PATH)
                    return false;
                // left swipe
                if(e1.getX() - e2.getX() > REL_SWIPE_MIN_DISTANCE && Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) {
                	rollMonth(true);
                	SetGridViewAdapter();
                	((GridView) mDialog.findViewById(R.id.calendar_grid)).invalidateViews();
                // right swipe
                }  else if (e2.getX() - e1.getX() > REL_SWIPE_MIN_DISTANCE && Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) {
                	rollMonth(false);
                	SetGridViewAdapter();
                	((GridView) mDialog.findViewById(R.id.calendar_grid)).invalidateViews();
                }
            } catch (Exception e) {
                // nothing
            }
            return false;
        }
    }
	
	public class calendarGridAdapter extends BaseAdapter {
		//private Context mContext;
		int mDayOfMonthStart;
		int mDayOfMonthEnd;
		int mMonthToDisplay;
		int mCurrentDay;
		int mSquarePosition;
		private final Calendar mCal;
		int mItemBG;
		int mDaysPadded;
		
		public calendarGridAdapter(Context context, int monthToShow) {
			//mContext = context;
			mCurrentDay = 1;
			mMonthToDisplay = monthToShow;
			mItemBG = R.drawable.calendar_item_unselected;
			mDaysPadded = 0;
			
			//find where the first day of month starts
			mCal = Calendar.getInstance();
			mCal.set(Calendar.MONTH, mMonthToDisplay);
			mCal.set(Calendar.DATE, mCurrentDay);
    		
    		mDayOfMonthEnd = mCal.getActualMaximum(Calendar.DAY_OF_MONTH);
    		mDayOfMonthStart = mCal.get(Calendar.DAY_OF_WEEK);
    		
    		mSquarePosition = 1;
		}
		
		public int getCount() {
			return 35; //total number of squares to show in calendar (5 weeks)
		}
		
		public Object getItem(int position) {
			return mDialog.findViewById(R.id.calendar_grid).findViewById(position);
		}
		
		public long getItemId(int position) {
			return position;
		}
		
		public View getView(int position, View convertView, ViewGroup parent) {
			View itemView;
			LayoutInflater inflator;
			TextView dayItem;
			LinearLayout llItem;
			int daysInPrevMonth;
			
			if (convertView == null) {
				//inflate the calendar relative layout item
				inflator = getLayoutInflater();
		    	itemView = inflator.inflate(R.layout.calendar_item, parent, false);
		    	//grab the layout item as well as the text item
		    	llItem = (LinearLayout)itemView.findViewById(R.id.cal_item);
		    	dayItem = (TextView)itemView.findViewById(R.id.cal_item_text);
		    	llItem.setLayoutParams(new GridView.LayoutParams(75, 50));
		    	
		    	if (mDayOfMonthStart > mSquarePosition) {
		    		mCal.set(Calendar.MONTH, mMonthToDisplay - 1);
		    		daysInPrevMonth = mCal.getActualMaximum(Calendar.DAY_OF_MONTH);
		    		// zero base day of month start then subtract the square position
		    		daysInPrevMonth -= ((mDayOfMonthStart - 1) - mSquarePosition); 
		    		mDaysPadded++;
		    		dayItem.setText(" " + daysInPrevMonth);
		    		mItemBG = R.drawable.calendar_item_alt_unselected;
		    		llItem.setTag(R.string.alt, true);
		    	} else if (mCurrentDay > mDayOfMonthEnd) {
		    		mCurrentDay = 1;
		    		mCal.set(Calendar.MONTH, mMonthToDisplay + 1);
		    		dayItem.setText(" " + mCurrentDay);
		    		mItemBG = R.drawable.calendar_item_alt_unselected;
		    		llItem.setTag(R.string.alt, true);
		    		mCurrentDay++;
		    	} else {
		    		if (mSquarePosition > (mDayOfMonthEnd + mDaysPadded)) {
		    			mItemBG = R.drawable.calendar_item_alt_unselected;
		    			llItem.setTag(R.string.alt, true);
		    		} else {
		    			mItemBG = R.drawable.calendar_item_unselected;
		    			mCal.set(Calendar.MONTH, mMonthToDisplay);
		    			llItem.setTag(R.string.alt, false);
		    		}
		    		dayItem.setText(" " + mCurrentDay);
		    		mCurrentDay++;
		    	}
		    	
		    	if (mSquarePosition % 7 == 0) {
		    		llItem.setTag(R.string.day_of_week, 7);
		    	} else {
		    		llItem.setTag(R.string.day_of_week, mSquarePosition % 7);
		    	}
		    	llItem.setTag(R.string.year_val, mCal.get(Calendar.YEAR));
		    	llItem.setTag(R.string.month_val, mCal.get(Calendar.MONTH));
		    	llItem.setBackgroundResource(mItemBG);
		    	llItem.setId(mSquarePosition + 00);
		    	
		    	itemView = llItem;
		    	
    			mSquarePosition++;
			} else {
				itemView = convertView;
			}
			
			return itemView;
		}
	}

	
}